"""
验证码模型
"""
import random
import string
from datetime import datetime, timedelta
from sqlalchemy import Column, String, DateTime, Boolean
from sqlalchemy.orm import Session
from sqlalchemy import and_, or_
from backend.app.models.base import BaseModel
from backend.app.db.database import get_db

class VerificationCode(BaseModel):
    """验证码模型"""
    __tablename__ = "verification_codes"

    email = Column(String(100), nullable=False, index=True)
    code = Column(String(6), nullable=False)
    is_used = Column(Boolean, default=False)
    expires_at = Column(DateTime, nullable=False)

    @classmethod
    def create_code(cls, email: str) -> str:
        """
        创建验证码
        
        Args:
            email: 邮箱地址
            
        Returns:
            str: 生成的验证码
        """
        db = next(get_db())
        try:
            # 检查是否存在旧验证码
            old_code = db.query(cls).filter(
                and_(
                    cls.email == email,
                    cls.is_used == False,
                    cls.expires_at > datetime.utcnow()
                )
            ).first()
            
            if old_code:
                # 如果存在未使用的有效验证码，直接返回
                return old_code.code
            
            # 生成新的验证码
            code = ''.join(random.choices(string.digits, k=6))
            expires_at = datetime.utcnow() + timedelta(minutes=1)
            
            # 创建新验证码记录
            verification_code = cls(
                email=email,
                code=code,
                expires_at=expires_at
            )
            
            db.add(verification_code)
            db.commit()
            db.refresh(verification_code)
            
            return code
        except Exception as e:
            db.rollback()
            raise e

    @classmethod
    def verify_code(cls, db: Session, email: str, code: str) -> bool:
        """
        验证验证码
        
        Args:
            db: 数据库会话
            email: 邮箱地址
            code: 验证码
            
        Returns:
            bool: 验证是否成功
        """
        try:
            verification_code = db.query(cls).filter(
                and_(
                    cls.email == email,
                    cls.code == code,
                    cls.is_used == False,
                    cls.expires_at > datetime.utcnow()
                )
            ).first()
            
            if verification_code:
                # 标记验证码为已使用
                verification_code.is_used = True
                db.commit()
                return True
                
            return False
        except Exception as e:
            db.rollback()
            raise e

    def is_expired(self) -> bool:
        """检查验证码是否过期"""
        return datetime.utcnow() > self.expires_at

    def is_valid(self) -> bool:
        """检查验证码是否有效"""
        return not self.is_used and not self.is_expired() 